﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using libtcodWrapper;
using Console = libtcodWrapper.Console;

namespace HDHack
{
    class Program : IDisposable
    {

        RootConsole rootConsole;        
        KeyPress key = new KeyPress();

        public Console mapConsole;
        public Console logConsole;
        public Console infoConsole;

        public Player player;
        public Dungeon d;
        List<string> displayLog = new List<string>();
        //List<Tile> tiles = new List<Tile>();
        
        int topLogIndex;

        public TCODRandom rand = new TCODRandom();


        public const int MAP_SCREEN_WIDTH = 75;
        public const int MAP_SCREEN_HEIGHT = 56;

        const int MAP_SCREEN_X = 24;
        const int MAP_SCREEN_Y = 5;

        const int LOG_SCREEN_WIDTH = 100;
        const int LOG_SCREEN_HEIGHT = 14;

        const int LOG_SCREEN_X = 0;
        const int LOG_SCREEN_Y = 61;

        const int INFO_SCREEN__WIDTH = 25;
        const int INFO_SCREEN_HEIGHT = 56;

        const int INFO_SCREEN_X = 0;
        const int INFO_SCREEN_Y = 5;

        LootInterface li;
        InventoryInterface ii;
        EquipItemInterface ei;
        UnEquipInterface uei;
        DropInterface di;
        #region Helpers

        public void WriteToLog(string Message)
        {
            displayLog.Add(Message);
            topLogIndex = displayLog.Count - 1;
        }
        #endregion

        void render_info(bool first, KeyPress key)
        {
            if (first)
            {
                infoConsole.Clear();
            }

            if (d.ComplexCommand)
            {

                if (li.IsActive)
                {
                    li.ProcessChoice(key);
                }
                if (ei.IsActive)
                {
                    ei.ProcessChoice(key);
                }
                if (uei.IsActive)
                {
                    uei.ProcessChoice(key);
                }
                if (di.IsActive)
                {
                    di.ProcessChoice(key);
                }

            }

            if (!d.ComplexCommand)
            {
                //loot something (pickup items
                if (key.Character == 'l')
                {
                    d.ComplexCommand = true;
                    li.DisplayLoot(d.Levels[d.CurrentLevelIndex].tiles[player.x, player.y].items);
                }
                //display inventory
                else if (key.Character == 'i')
                {
                    ii.DisplayInventory();
                }
                // equip items
                else if (key.Character == 'e')
                {
                    d.ComplexCommand = true;
                    ei.DisplayEquipableInventory();
                }
                // show equiped items
                else if (key.Character == 'I')
                {
                    ei.DisplayEquipedItems();
                }
                //remove equiped items
                else if (key.Character == 'E')
                {
                    d.ComplexCommand = true;
                    uei.DisplayEquipedItems();
                }
                //drop items
                else if (key.Character == 'd')
                {
                    d.ComplexCommand = true;
                    di.DisplayDropableInventory();
                }


            }



            
            
            

        }

        void render_log(bool first, KeyPress key)
        {            
            logConsole.Clear();

            if (first)
            {
                logConsole.Clear();
                logConsole.ForegroundColor = (ColorPresets.Black);                
                logConsole.ForegroundColor = (ColorPresets.White);               
            }



            if (key.KeyCode == KeyCode.TCODK_DOWN)
            {
                if ((topLogIndex + 1) < displayLog.Count)
                {
                    topLogIndex++;
                }
            }
            else if (key.KeyCode == KeyCode.TCODK_UP)
            {
                if ((topLogIndex) > 11)
                {
                    topLogIndex--;
                }
            }

            int logcounter = 1;
            for (int li = topLogIndex - 10; li <= topLogIndex; li++)
            {
                logConsole.PrintLine(displayLog[li], 1, logcounter, LineAlignment.Left);
                logcounter++;
            }

        }


        private int Run(string[] args)
        {
            try
            {


                displayLog.Add("");
                displayLog.Add("");
                displayLog.Add("");
                displayLog.Add("");
                displayLog.Add("");                
                displayLog.Add("");
                displayLog.Add("");
                displayLog.Add("");
                displayLog.Add("");
                displayLog.Add("");
                displayLog.Add("Welcome to HDHack");
                
                topLogIndex = displayLog.Count - 1;

               
                string font = "celtic_garamond_10x10_gs_tc.png";
                //string font = "terminal8x8_gs_tc.png";

                CustomFontRequestFontTypes flags = CustomFontRequestFontTypes.Grayscale | CustomFontRequestFontTypes.LayoutTCOD;
                CustomFontRequest fontReq = new CustomFontRequest(font, flags, 32, 8);
                
                RootConsole.WindowTitle = "HDHack";
                RootConsole.Height = 75;
                
                RootConsole.Width = 100;
                RootConsole.Fullscreen = false;
                RootConsole.Font = fontReq;
                //RootConsole.
                rootConsole = RootConsole.GetInstance();
                mapConsole = RootConsole.GetNewConsole(MAP_SCREEN_WIDTH, MAP_SCREEN_HEIGHT);
                logConsole = RootConsole.GetNewConsole(LOG_SCREEN_WIDTH, LOG_SCREEN_HEIGHT);
                infoConsole = RootConsole.GetNewConsole(INFO_SCREEN__WIDTH, INFO_SCREEN_HEIGHT);
                bool first = true;

                player = new Player(39, 11, '@', 20, 10, 5);
                player.TravelDir = 2;
                d = new Dungeon(3, this);
                d.GenerateLevels();
                d.Levels[player.CurrentLevelIndex].PlacePlayer();
                li = new LootInterface(player, infoConsole, d);
                ii = new InventoryInterface(player, infoConsole, d);
                ei = new EquipItemInterface(player, infoConsole, d);
                uei = new UnEquipInterface(player, infoConsole, d);
                di = new DropInterface(player, infoConsole, d);
                do
                {                    

                    rootConsole.Clear();

                    rootConsole.ForegroundColor = (ColorPresets.Green);
                    rootConsole.BackgroundColor = ColorPresets.Black;
                    
                    rootConsole.PrintLine("HP: " + player.hp.ToString(), 2, 1, LineAlignment.Left);

                    logConsole.BackgroundColor = (ColorPresets.White);
                    logConsole.ForegroundColor = (ColorPresets.Black);

                    infoConsole.BackgroundColor = (ColorPresets.White);
                    infoConsole.ForegroundColor = (ColorPresets.Black);

                    if (player.CurrentLevelIndex != d.CurrentLevelIndex)
                    {
                        d.Levels[player.CurrentLevelIndex].PlacePlayer();
                    }

                    d.Levels[player.CurrentLevelIndex].render_level(first, key);                    
                    mapConsole.Blit(0, 0, MAP_SCREEN_WIDTH, MAP_SCREEN_HEIGHT, rootConsole, MAP_SCREEN_X, MAP_SCREEN_Y, 255);

                    render_log(first, key);
                    logConsole.Blit(0, 0, LOG_SCREEN_WIDTH, LOG_SCREEN_HEIGHT, rootConsole, LOG_SCREEN_X, LOG_SCREEN_Y, 255);

                    render_info(first, key);
                    infoConsole.Blit(0, 0, INFO_SCREEN__WIDTH, INFO_SCREEN_HEIGHT, rootConsole, INFO_SCREEN_X, INFO_SCREEN_Y, 255);

                    rootConsole.Flush();
                    key = Keyboard.CheckForKeypress(KeyPressType.Pressed);


                    if (player.CurrentLevelIndex != d.CurrentLevelIndex)
                    {
                        first = true;
                        d.CurrentLevelIndex = player.CurrentLevelIndex;
                    }
                    else
                    {
                        first = false;
                    }


                }
                while (!rootConsole.IsWindowClosed());
            }
            catch (Exception ex)
            {
                WriteToLog(ex.ToString());
            }
            return 0;
        }

        public void Dispose()
        {
            rootConsole.Dispose();

        }        


        static int Main(string[] args)
        {


            using (Program p = new Program())
            {
                return p.Run(args);
            }
            


        }
    }

    
}
